import config from '../api/config.js';
import LoginUtils from './loginUtils.js';

/**
 * 通用请求工具类
 */
class Request {
  /**
   * 发起请求
   * @param {Object} options 请求配置
   * @returns {Promise} 返回Promise
   */
  static request(options) {
    // 设置默认配置
    const defaultOptions = {
      header: {
        'Content-Type': 'application/json'
      },
      timeout: 10000
    };

    // 合并配置
    const finalOptions = {
      ...defaultOptions,
      ...options,
      header: {
        ...defaultOptions.header,
        ...options.header
      }
    };

    // 添加token到请求头（如果存在）
    const token = uni.getStorageSync('token');
    if (token) {
      finalOptions.header['Authorization'] = `Bearer ${token}`;
    }

    return new Promise((resolve, reject) => {
      uni.request({
        ...finalOptions,
        success: (res) => {
          this.handleSuccess(res, resolve, reject);
        },
        fail: (err) => {
          this.handleFail(err, reject);
        }
      });
    });
  }

  /**
   * 统一处理请求成功响应
   * @param {Object} res 响应对象
   * @param {Function} resolve Promise resolve函数
   * @param {Function} reject Promise reject函数
   */
  static handleSuccess(res, resolve, reject) {
    // 处理401状态码，统一调用登录
    // console.log(res);
    if (res.data.code === 401) {
      this.handleUnauthorized();
      reject(new Error('未授权，请重新登录'));
      return;
    }

    // 处理HTTP状态码不是200的情况
    if (res.statusCode !== 200) {
      const errorMsg = `请求失败: ${res.statusCode}`;
      uni.showToast({
        title: errorMsg,
        icon: 'none'
      });
      reject(new Error(errorMsg));
      return;
    }

    // 处理业务状态码
    const data = res.data;
    if (data.code !== 0) {
      const errorMsg = data.msg || '请求失败';
      uni.showToast({
        title: errorMsg,
        icon: 'none'
      });
      reject(new Error(errorMsg));
      return;
    }

    // 成功返回数据
    resolve(data.data);
  }

  /**
   * 统一处理请求失败
   * @param {Object} err 错误对象
   * @param {Function} reject Promise reject函数
   */
  static handleFail(err, reject) {
    const errorMsg = err.errMsg || '网络请求失败';
    uni.showToast({
      title: errorMsg,
      icon: 'none'
    });
    reject(err);
  }

  /**
   * 处理401未授权状态
   */
  static handleUnauthorized() {
    // 清除本地存储的登录信息
    uni.removeStorageSync('openId');
    uni.removeStorageSync('token');
    
    // 静默登录
    // uni.showToast({
    //   title: '登录已过期，请重新登录',
    //   icon: 'none'
    // });
    
    // 重新执行登录流程
    setTimeout(() => {
      LoginUtils.checkAndHandleLogin();
    }, 1500);
  }

  /**
   * GET请求
   * @param {string} url 请求地址
   * @param {Object} data 请求参数
   * @param {Object} options 其他配置
   * @returns {Promise}
   */
  static get(url, data = {}, options = {}) {
    return this.request({
      url: url.startsWith('http') ? url : `${config.apiBaseUrl}${url}`,
      method: 'GET',
      data,
      ...options
    });
  }

  /**
   * POST请求
   * @param {string} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} options 其他配置
   * @returns {Promise}
   */
  static post(url, data = {}, options = {}) {
    return this.request({
      url: url.startsWith('http') ? url : `${config.apiBaseUrl}${url}`,
      method: 'POST',
      data,
      ...options
    });
  }

  /**
   * PUT请求
   * @param {string} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} options 其他配置
   * @returns {Promise}
   */
  static put(url, data = {}, options = {}) {
    return this.request({
      url: url.startsWith('http') ? url : `${config.apiBaseUrl}${url}`,
      method: 'PUT',
      data,
      ...options
    });
  }

  /**
   * DELETE请求
   * @param {string} url 请求地址
   * @param {Object} data 请求参数
   * @param {Object} options 其他配置
   * @returns {Promise}
   */
  static delete(url, data = {}, options = {}) {
    return this.request({
      url: url.startsWith('http') ? url : `${config.apiBaseUrl}${url}`,
      method: 'DELETE',
      data,
      ...options
    });
  }

  /**
   * DELETE请求，根据ID删除资源
   * @param {string} urlTemplate 包含{id}的URL模板
   * @param {string|number} id 资源ID
   * @returns {Promise}
   */
  static deleteById(urlTemplate, id) {
  return this.request({
    url: `${config.apiBaseUrl}${urlTemplate.replace('{id}', id)}`,
    method: 'DELETE'
  });
}
}

export default Request;